open Base

type source = int
type value = int

let time = 0
let next_id = ref 1
let create () =
  let s = !next_id in
  Int.incr next_id ; s

let to_string = function
  | 0 -> "Time"
  | n -> Printf.sprintf "<src:%d>" n

module Cmp : Comparable.S with type t = source = Int
include Cmp

type set = (t, comparator_witness) Set.t
type 'a map = (t, 'a, comparator_witness) Map.t
let empty_set = Set.empty (module Cmp)
let empty_map = Map.empty (module Cmp)

let singleton s = Set.singleton (module Cmp) s

module State = struct
  type t = value map
  let empty = empty_map
  let set i v m = Map.set m ~key:i ~data:v
  let of_time ts = set time ts empty
  let get_exn i m = match Map.find m i with
    | Some(v) -> v
    | None -> failwith "source unset"
end

module Private = struct
  let next_id ~diff = !next_id + diff
end
